home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet multimedia / Muzyka / Edytory sampli (probek dzwieku) / ZynAddSubFX_2.2.0 / Setup_ZynAddSubFX-2.2.0.exe / source code / Effects / Reverb.C < prev    next >
C/C++ Source or Header  |  2005-03-14  |  10KB  |  439 lines

  1. /*
  2.   ZynAddSubFX - a software synthesizer
  3.  
  4.   Reverb.C - Reverberation effect
  5.   Copyright (C) 2002-2005 Nasca Octavian Paul
  6.   Author: Nasca Octavian Paul
  7.  
  8.   This program is free software; you can redistribute it and/or modify
  9.   it under the terms of version 2 of the GNU General Public License 
  10.   as published by the Free Software Foundation.
  11.  
  12.   This program is distributed in the hope that it will be useful,
  13.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.   GNU General Public License (version 2) for more details.
  16.  
  17.   You should have received a copy of the GNU General Public License (version 2)
  18.   along with this program; if not, write to the Free Software Foundation,
  19.   Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  20.  
  21. */
  22.  
  23. #include <stdio.h>
  24.  
  25. #include <math.h>
  26. #include <stdlib.h>
  27. #include "Reverb.h"
  28.  
  29. /*TODO: EarlyReflections,Prdelay,Perbalance */
  30.  
  31. Reverb::Reverb(int insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_){
  32.     efxoutl=efxoutl_;
  33.     efxoutr=efxoutr_;
  34.     inputbuf=new REALTYPE[SOUND_BUFFER_SIZE];
  35.     filterpars=NULL;
  36.  
  37.     insertion=insertion_;
  38.     //defaults
  39.     Ppreset=0;
  40.     Pvolume=48; 
  41.     Ppan=64; 
  42.     Ptime=64;
  43.     Pidelay=40; 
  44.     Pidelayfb=0; 
  45.     Prdelay=0; 
  46.     Plpf=127;
  47.     Phpf=0; 
  48.     Perbalance=64; 
  49.     Plohidamp=80;
  50.     Ptype=1;
  51.     Proomsize=64;roomsize=1.0;rs=1.0;
  52.  
  53.     for (int i=0;i<REV_COMBS*2;i++) {
  54.     comblen[i]=800+(int)(RND*1400);
  55.     combk[i]=0;
  56.     lpcomb[i]=0;
  57.     combfb[i]=-0.97;
  58.     comb[i]=NULL;
  59.     };    
  60.  
  61.     for (int i=0;i<REV_APS*2;i++) {
  62.     aplen[i]=500+(int)(RND*500);
  63.     apk[i]=0;
  64.     ap[i]=NULL;
  65.     };
  66.     
  67.     lpf=NULL;hpf=NULL;//no filter
  68.     idelay=NULL;
  69.  
  70.     setpreset(Ppreset);
  71.     cleanup();//do not call this before the comb initialisation
  72. };
  73.  
  74.  
  75. Reverb::~Reverb(){
  76.     int i;
  77.     if (idelay!=NULL) delete idelay;
  78.     if (hpf!=NULL) delete hpf;
  79.     if (lpf!=NULL) delete lpf;
  80.  
  81.     for (i=0;i<REV_APS*2;i++) delete ap[i];
  82.     for (i=0;i<REV_COMBS*2;i++) delete comb[i];
  83.  
  84.     delete [] inputbuf;
  85. };
  86.  
  87. /*
  88.  * Cleanup the effect
  89.  */
  90. void Reverb::cleanup(){
  91.     int i,j;
  92.     for (i=0;i<REV_COMBS*2;i++){
  93.     lpcomb[i]=0.0;
  94.     for (j=0;j<comblen[i];j++) comb[i][j]=0.0;
  95.     };
  96.  
  97.     for (i=0;i<REV_APS*2;i++) 
  98.     for (j=0;j<aplen[i];j++) ap[i][j]=0.0;
  99.  
  100.     if (idelay!=NULL) for (i=0;i<idelaylen;i++) idelay[i]=0.0;
  101.  
  102.     if (hpf!=NULL) hpf->cleanup();
  103.     if (lpf!=NULL) lpf->cleanup();
  104.  
  105. };
  106.  
  107. /*
  108.  * Process one channel; 0=left,1=right
  109.  */
  110. void Reverb::processmono(int ch,REALTYPE *output){
  111.     int i,j;
  112.     REALTYPE fbout,tmp;
  113.     //TODO: implement the high part from lohidamp
  114.     
  115.     for (j=REV_COMBS*ch;j<REV_COMBS*(ch+1);j++){
  116.  
  117.     int ck=combk[j];
  118.     int comblength=comblen[j];
  119.     REALTYPE lpcombj=lpcomb[j];
  120.  
  121.     for (i=0;i<SOUND_BUFFER_SIZE;i++){
  122.             fbout=comb[j][ck]*combfb[j];
  123.             fbout=fbout*(1.0-lohifb)+lpcombj*lohifb;
  124.         lpcombj=fbout;    
  125.  
  126.         comb[j][ck]=inputbuf[i]+fbout;
  127.         output[i]+=fbout;
  128.  
  129.         if ((++ck)>=comblength) ck=0;
  130.     };
  131.  
  132.     combk[j]=ck;
  133.     lpcomb[j]=lpcombj;
  134.     };
  135.  
  136.     for (j=REV_APS*ch;j<REV_APS*(1+ch);j++){
  137.     int ak=apk[j];
  138.     int aplength=aplen[j];
  139.     for (i=0;i<SOUND_BUFFER_SIZE;i++){
  140.         tmp=ap[j][ak];
  141.         ap[j][ak]=0.7*tmp+output[i];
  142.         output[i]=tmp-0.7*ap[j][ak];
  143.         if ((++ak)>=aplength) ak=0;
  144.     };
  145.     apk[j]=ak;
  146.     };
  147. };
  148.  
  149. /*
  150.  * Effect output
  151.  */
  152. void Reverb::out(REALTYPE *smps_l, REALTYPE *smps_r){
  153.     int i;
  154.     if ((Pvolume==0)&&(insertion!=0)) return;
  155.     
  156.     for (i=0;i<SOUND_BUFFER_SIZE;i++) {
  157.     inputbuf[i]=(smps_l[i]+smps_r[i])/2.0;
  158.     //Initial delay r
  159.     if (idelay!=NULL){
  160.             REALTYPE tmp=inputbuf[i]+idelay[idelayk]*idelayfb;
  161.             inputbuf[i]=idelay[idelayk];
  162.             idelay[idelayk]=tmp;        
  163.             idelayk++;if (idelayk>=idelaylen) idelayk=0;
  164.     };
  165.     };
  166.  
  167.     if (lpf!=NULL) lpf->filterout(inputbuf);
  168.     if (hpf!=NULL) hpf->filterout(inputbuf);
  169.  
  170.     processmono(0,efxoutl);//left
  171.     processmono(1,efxoutr);//right
  172.     
  173.     REALTYPE lvol=rs/REV_COMBS*pan;
  174.     REALTYPE rvol=rs/REV_COMBS*(1.0-pan);
  175.     if (insertion!=0){
  176.     lvol*=2;rvol*=2;
  177.     };
  178.     for (int i=0;i<SOUND_BUFFER_SIZE;i++){
  179.     efxoutl[i]*=lvol;
  180.     efxoutr[i]*=rvol;
  181.     };
  182. };
  183.  
  184.  
  185. /*
  186.  * Parameter control
  187.  */
  188. void Reverb::setvolume(unsigned char Pvolume){
  189.     this->Pvolume=Pvolume;
  190.     if (insertion==0) {
  191.     outvolume=pow(0.01,(1.0-Pvolume/127.0))*4.0;
  192.     volume=1.0;
  193.     } else {
  194.     volume=outvolume=Pvolume/127.0;
  195.     if (Pvolume==0) cleanup();
  196.     };
  197. };
  198.  
  199. void Reverb::setpan(unsigned char Ppan){
  200.     this->Ppan=Ppan;
  201.     pan=(REALTYPE)Ppan/127.0;
  202. };
  203.  
  204. void Reverb::settime(unsigned char Ptime){
  205.     int i;
  206.     REALTYPE t;
  207.     this->Ptime=Ptime;
  208.     t=pow(60.0,(REALTYPE)Ptime/127.0)-0.97;
  209.  
  210.     for (i=0;i<REV_COMBS*2;i++){
  211.     combfb[i]=-exp((REALTYPE)comblen[i]/(REALTYPE)SAMPLE_RATE*log(0.001)/t);
  212.     //the feedback is negative because it removes the DC
  213.     };
  214. };
  215.  
  216. void Reverb::setlohidamp(unsigned char Plohidamp){
  217.     REALTYPE x;    
  218.     
  219.     if (Plohidamp<64) Plohidamp=64;//remove this when the high part from lohidamp will be added
  220.     
  221.     this->Plohidamp=Plohidamp;
  222.     if (Plohidamp==64) {
  223.     lohidamptype=0;
  224.     lohifb=0.0;
  225.     } else {
  226.         if (Plohidamp<64) lohidamptype=1;
  227.             if (Plohidamp>64) lohidamptype=2;
  228.         x=fabs((REALTYPE)(Plohidamp-64)/64.1);
  229.         lohifb=x*x;
  230.     };
  231. };
  232.  
  233. void Reverb::setidelay(unsigned char Pidelay){
  234.     REALTYPE delay;
  235.     this->Pidelay=Pidelay;
  236.     delay=pow(50*Pidelay/127.0,2)-1.0;
  237.     
  238.     if (idelay!=NULL) delete (idelay);
  239.     idelay=NULL;
  240.     
  241.     idelaylen=(int) (SAMPLE_RATE*delay/1000);
  242.     if (idelaylen>1) {
  243.     idelayk=0;
  244.     idelay=new REALTYPE[idelaylen];
  245.         for (int i=0;i<idelaylen;i++) idelay[i]=0.0;
  246.     };
  247. };
  248.  
  249. void Reverb::setidelayfb(unsigned char Pidelayfb){
  250.     this->Pidelayfb=Pidelayfb;
  251.     idelayfb=Pidelayfb/128.0;
  252. };
  253.  
  254. void Reverb::sethpf(unsigned char Phpf){
  255.     this->Phpf=Phpf;
  256.     if (Phpf==0) {//No HighPass
  257.         if (hpf!=NULL) delete(hpf);
  258.         hpf=NULL;
  259.     }
  260.        else{
  261.         REALTYPE fr=exp(pow(Phpf/127.0,0.5)*log(10000.0))+20.0;
  262.     if (hpf==NULL) hpf=new AnalogFilter(3,fr,1,0);
  263.             else hpf->setfreq(fr);
  264.     };
  265. };
  266.  
  267. void Reverb::setlpf(unsigned char Plpf){
  268.     this->Plpf=Plpf;
  269.     if (Plpf==127) {//No LowPass
  270.         if (lpf!=NULL) delete(lpf);
  271.         lpf=NULL;
  272.     }
  273.        else{
  274.         REALTYPE fr=exp(pow(Plpf/127.0,0.5)*log(25000.0))+40;
  275.     if (lpf==NULL) lpf=new AnalogFilter(2,fr,1,0);
  276.             else lpf->setfreq(fr);
  277.     };
  278. };
  279.  
  280. void Reverb::settype(unsigned char Ptype){
  281.     const int NUM_TYPES=2;
  282.     int combtunings[NUM_TYPES][REV_COMBS]={
  283.     //this is unused (for random)
  284.     {0,0,0,0,0,0,0,0},
  285.     //Freeverb by Jezar at Dreampoint
  286.     {1116,1188,1277,1356,1422,1491,1557,1617}
  287.     };
  288.     int aptunings[NUM_TYPES][REV_APS]={
  289.     //this is unused (for random)
  290.     {0,0,0,0},
  291.     //Freeverb by Jezar at Dreampoint
  292.     {225,341,441,556}
  293.     };
  294.  
  295.     if (Ptype>=NUM_TYPES) Ptype=NUM_TYPES-1;
  296.     this->Ptype=Ptype;
  297.     
  298.     REALTYPE tmp;
  299.     for (int i=0;i<REV_COMBS*2;i++) {
  300.     if (Ptype==0) tmp=800.0+(int)(RND*1400.0);
  301.         else tmp=combtunings[Ptype][i%REV_COMBS];
  302.     tmp*=roomsize;
  303.     if (i>REV_COMBS) tmp+=23.0;
  304.     tmp*=SAMPLE_RATE/44100.0;//adjust the combs according to the samplerate
  305.     if (tmp<10) tmp=10;
  306.     
  307.     comblen[i]=(int) tmp;
  308.     combk[i]=0;
  309.     lpcomb[i]=0;
  310.     if (comb[i]!=NULL) delete comb[i];
  311.     comb[i]=new REALTYPE[comblen[i]];
  312.     };    
  313.  
  314.     for (int i=0;i<REV_APS*2;i++) {
  315.     if (Ptype==0) tmp=500+(int)(RND*500);
  316.         else tmp=aptunings[Ptype][i%REV_APS];
  317.     tmp*=roomsize;    
  318.     if (i>REV_APS) tmp+=23.0;
  319.     tmp*=SAMPLE_RATE/44100.0;//adjust the combs according to the samplerate
  320.     if (tmp<10) tmp=10;
  321.     aplen[i]=(int) tmp;
  322.     apk[i]=0;
  323.     if (ap[i]!=NULL) delete ap[i];
  324.     ap[i]=new REALTYPE[aplen[i]];
  325.     };
  326.     settime(Ptime);
  327.     cleanup();
  328. };
  329.  
  330. void Reverb::setroomsize(unsigned char Proomsize){
  331.     if (Proomsize==0) Proomsize=64;//this is because the older versions consider roomsize=0
  332.     this->Proomsize=Proomsize;
  333.     roomsize=(Proomsize-64.0)/64.0;
  334.     if (roomsize>0.0) roomsize*=2.0;
  335.     roomsize=pow(10.0,roomsize);
  336.     rs=sqrt(roomsize);
  337.     settype(Ptype);    
  338. };
  339.  
  340. void Reverb::setpreset(unsigned char npreset){
  341.     const int PRESET_SIZE=12;
  342.     const int NUM_PRESETS=13;
  343.     unsigned char presets[NUM_PRESETS][PRESET_SIZE]={
  344.     //Cathedral1
  345.     {80,64,63,24,0,0,0,85,5,83,1,64},
  346.         //Cathedral2
  347.     {80,64,69,35,0,0,0,127,0,71,0,64},
  348.     //Cathedral3
  349.     {80,64,69,24,0,0,0,127,75,78,1,85},
  350.     //Hall1
  351.     {90,64,51,10,0,0,0,127,21,78,1,64},
  352.     //Hall2
  353.     {90,64,53,20,0,0,0,127,75,71,1,64},
  354.     //Room1
  355.     {100,64,33,0,0,0,0,127,0,106,0,30},
  356.     //Room2
  357.     {100,64,21,26,0,0,0,62,0,77,1,45},
  358.     //Basement
  359.     {110,64,14,0,0,0,0,127,5,71,0,25},
  360.     //Tunnel
  361.     {85,80,84,20,42,0,0,51,0,78,1,105},
  362.     //Echoed1
  363.     {95,64,26,60,71,0,0,114,0,64,1,64},
  364.     //Echoed2
  365.     {90,64,40,88,71,0,0,114,0,88,1,64},
  366.     //VeryLong1
  367.     {90,64,93,15,0,0,0,114,0,77,0,95},
  368.     //VeryLong2
  369.     {90,64,111,30,0,0,0,114,90,74,1,80}};
  370.  
  371.     if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1;
  372.     for (int n=0;n<PRESET_SIZE;n++) changepar(n,presets[npreset][n]);
  373.     if (insertion!=0) changepar(0,presets[npreset][0]/2);//lower the volume if reverb is insertion effect
  374.     Ppreset=npreset;
  375. };
  376.  
  377.  
  378. void Reverb::changepar(int npar,unsigned char value){
  379.     switch (npar){
  380.     case 0: setvolume(value);
  381.         break;
  382.     case 1: setpan(value);
  383.         break;
  384.     case 2: settime(value);
  385.         break;
  386.     case 3: setidelay(value);
  387.         break;
  388.     case 4: setidelayfb(value);
  389.         break;
  390. //    case 5: setrdelay(value);
  391. //        break;
  392. //    case 6: seterbalance(value);
  393. //        break;
  394.     case 7: setlpf(value);
  395.         break;
  396.     case 8: sethpf(value);
  397.         break;
  398.     case 9: setlohidamp(value);
  399.         break;
  400.     case 10:settype(value);
  401.         break;
  402.     case 11:setroomsize(value);
  403.         break;
  404.     };
  405. };
  406.  
  407. unsigned char Reverb::getpar(int npar){
  408.     switch (npar){
  409.     case 0: return(Pvolume);
  410.         break;
  411.     case 1: return(Ppan);
  412.         break;
  413.     case 2: return(Ptime);
  414.         break;
  415.     case 3: return(Pidelay);
  416.         break;
  417.     case 4: return(Pidelayfb);
  418.         break;
  419. //    case 5: return(Prdelay);
  420. //        break;
  421. //    case 6: return(Perbalance);
  422. //        break;
  423.     case 7: return(Plpf);
  424.         break;
  425.     case 8: return(Phpf);
  426.         break;
  427.     case 9: return(Plohidamp);
  428.         break;
  429.     case 10:return(Ptype);
  430.         break;
  431.     case 11:return(Proomsize);
  432.         break;
  433.     };
  434.     return(0);//in case of bogus "parameter"
  435. };
  436.  
  437.  
  438.  
  439.